"""
Yuxi-Know MCP适配器
使用fastapi_mcp将Yuxi-Know功能暴露为MCP工具
"""
import os
import logging
from typing import Optional, Any
from fastapi import FastAPI, APIRouter, Query, Body
from fastapi import Depends, HTTPException
from fastapi.responses import JSONResponse

# MCP配置
MCP_ENABLED = os.getenv("MCP_ENABLED", "true").lower() == "true"
MCP_MOUNT_PATH = os.getenv("MCP_MOUNT_PATH", "/mcp")
MCP_SERVER_NAME = os.getenv("MCP_SERVER_NAME", "Yuxi-Know Knowledge System")
MCP_SERVER_VERSION = os.getenv("MCP_SERVER_VERSION", "1.0.0")

# 日志配置
logger = logging.getLogger(__name__)

def create_mcp_router() -> APIRouter:
    """
    创建MCP工具专用的路由器，包含所有MCP工具对应的FastAPI端点
    """
    mcp_router = APIRouter(prefix="/mcp-tools", tags=["mcp"])

    # =============================================================================
    # === 系统健康检查工具 ===
    # =============================================================================
    @mcp_router.get("/health", operation_id="yuxi-know-health", response_model=dict)
    async def yuxi_know_health():
        """获取Yuxi-Know知识系统健康状态"""
        from server.mcp.yuxi_know_tools import get_system_health
        return await get_system_health()

    # =============================================================================
    # === 知识库查询工具 ===
    # =============================================================================
    @mcp_router.get("/knowledge/query", operation_id="yuxi-know-query-knowledge", response_model=dict)
    async def yuxi_know_query_knowledge(
        database_id: str = Query(..., description="知识库ID"),
        query: str = Query(..., description="查询内容"),
        top_k: int = Query(5, description="返回结果数量", ge=1, le=20),
        search_type: str = Query("hybrid", description="检索类型(local/global/hybrid/naive/mix)"),
        threshold: float = Query(0.7, description="相似度阈值", ge=0.0, le=1.0)
    ):
        """在Yuxi-Know知识库中查询相关内容，支持多种检索模式(local/global/hybrid/naive/mix)"""
        from server.mcp.yuxi_know_tools import query_knowledge_base, KnowledgeQueryInput

        input_data = KnowledgeQueryInput(
            database_id=database_id,
            query=query,
            top_k=top_k,
            search_type=search_type,
            threshold=threshold
        )
        return await query_knowledge_base(input_data)

    # =============================================================================
    # === 知识图谱查询工具 ===
    # =============================================================================
    @mcp_router.get("/graph/query", operation_id="yuxi-know-query-graph", response_model=dict)
    async def yuxi_know_query_graph(
        node_label: str = Query(..., description="图谱节点标签"),
        depth: int = Query(2, description="查询深度", ge=1, le=5),
        max_nodes: int = Query(100, description="最大节点数量", ge=1, le=1000)
    ):
        """查询知识图谱，获取相关子图结构和关联关系"""
        from server.mcp.yuxi_know_tools import query_knowledge_graph, GraphQueryInput

        input_data = GraphQueryInput(
            node_label=node_label,
            depth=depth,
            max_nodes=max_nodes
        )
        return await query_knowledge_graph(input_data)

    # =============================================================================
    # === 智能体对话工具 ===
    # =============================================================================
    @mcp_router.post("/chat/message", operation_id="yuxi-know-chat", response_model=dict)
    async def yuxi_know_chat(data: dict = Body(...)):
        """与AI智能体进行对话，支持上下文关联和知识库增强"""
        from server.mcp.yuxi_know_tools import chat_with_agent

        # 从请求数据中获取参数并转换为 ChatInput
        from server.mcp.yuxi_know_tools import ChatInput

        chat_data = ChatInput(
            agent_id=data.get("agent_id", "chatbot"),
            message=data.get("message"),
            thread_id=data.get("thread_id"),
            knowledge_base_ids=data.get("knowledge_base_ids", []),
            model_name=data.get("model_name"),
        )

        return await chat_with_agent(chat_data)

    # =============================================================================
    # === 知识库列表获取工具 ===
    # =============================================================================
    @mcp_router.get("/knowledge/bases", operation_id="yuxi-know-get-kbs", response_model=dict)
    async def yuxi_know_get_kbs():
        """获取所有可用的知识库列表和详细信息"""
        from server.mcp.yuxi_know_tools import get_knowledge_bases
        return await get_knowledge_bases()

    # =============================================================================
    # === 实体搜索工具 ===
    # =============================================================================
    @mcp_router.get("/graph/entities/search", operation_id="yuxi-know-search-entities", response_model=dict)
    async def yuxi_know_search_entities(
        entity_name: str = Query(..., description="实体名称"),
        limit: int = Query(10, description="返回结果数量", ge=1, le=50)
    ):
        """在知识图谱中搜索实体和关联关系"""
        try:
            from server.mcp.yuxi_know_tools import search_entities, EntitySearchInput

            input_data = EntitySearchInput(
                entity_name=entity_name,
                limit=limit
            )

            # 获取原始图数据
            result = await search_entities(input_data)

            # 将图数据转换为自然语言描述
            natural_language_description = _convert_graph_data_to_natural_language(
                result.entities,
                result.relationships,
                entity_name
            )

            return {
                "search_query": entity_name,
                "summary": natural_language_description["summary"],
                "entities_found": natural_language_description["entities"],
                "relationships_found": natural_language_description["relationships"],
                "total_entities": len(result.entities),
                "raw_data": {
                    "entities": result.entities[:5],  # 只返回前5个实体作为示例
                    "relationships": result.relationships[:5]  # 只返回前5个关系作为示例
                }
            }

        except Exception as e:
            logger.error(f"MCP实体搜索处理异常: {e}")
            return {
                "search_query": entity_name,
                "summary": f"搜索实体'{entity_name}'时发生错误: {str(e)}",
                "entities_found": [],
                "relationships_found": [],
                "total_entities": 0,
                "error": str(e)
            }

def _convert_graph_data_to_natural_language(entities, relationships, search_entity):
    """将图数据转换为大模型友好的自然语言描述"""

    # 去重和统计实体
    unique_entities = {}
    for entity in entities:
        name = entity.get('name', '未知实体')
        if name not in unique_entities:
            unique_entities[name] = []
        unique_entities[name].append(entity)

    # 去重和统计关系
    unique_relationships = []
    seen_relationships = set()

    for rel in relationships:
        source_name = _get_entity_name_by_id(rel.get('source_id'), entities)
        target_name = _get_entity_name_by_id(rel.get('target_id'), entities)
        rel_type = rel.get('type', '')

        # 创建关系唯一标识
        rel_key = f"{source_name}-{rel_type}-{target_name}"

        if rel_key not in seen_relationships and source_name and target_name:
            seen_relationships.add(rel_key)
            unique_relationships.append({
                "source": source_name,
                "relationship": rel_type,
                "target": target_name,
                "description": f"{source_name}是{target_name}的{rel_type}"
            })

    # 生成自然语言摘要
    entity_count = len(unique_entities)
    relationship_count = len(unique_relationships)

    if entity_count == 0:
        summary = f"未找到与'{search_entity}'相关的实体信息。"
    else:
        # 找到主实体（搜索目标）
        main_entity = search_entity if search_entity in unique_entities else list(unique_entities.keys())[0]

        # 生成摘要
        summary = f"找到了与'{main_entity}'相关的{entity_count}个实体和{relationship_count}个关系。"

        if main_entity in unique_entities:
            # 找出与主实体直接相关的关系
            main_relationships = [rel for rel in unique_relationships
                                if rel["source"] == main_entity or rel["target"] == main_entity]

            if main_relationships:
                summary += f" {main_entity}的主要关系包括："
                for i, rel in enumerate(main_relationships[:3]):  # 只显示前3个主要关系
                    if rel["source"] == main_entity:
                        summary += f"是{rel['target']}的{rel['relationship']}"
                    else:
                        summary += f"的{rel['relationship']}是{rel['source']}"

                    if i < len(main_relationships[:3]) - 1:
                        summary += "，"
                summary += "。"

    return {
        "summary": summary,
        "entities": list(unique_entities.keys()),
        "relationships": [rel["description"] for rel in unique_relationships[:10]]  # 只返回前10个关系描述
    }

def _get_entity_name_by_id(entity_id, entities):
    """根据实体ID获取实体名称"""
    for entity in entities:
        if entity.get('id') == entity_id:
            return entity.get('name', '')
    return ""

    # =============================================================================
    # === 工具列表获取工具 ===
    # =============================================================================
    @mcp_router.get("/tools/list", operation_id="yuxi-know-get-tools", response_model=dict)
    async def yuxi_know_get_tools():
        """获取系统中可用的工具列表"""
        from server.mcp.yuxi_know_tools import get_available_tools
        return await get_available_tools()

    # =============================================================================
    # === 图谱统计工具 ===
    # =============================================================================
    @mcp_router.get("/graph/stats", operation_id="yuxi-know-graph-stats", response_model=dict)
    async def yuxi_know_graph_stats():
        """获取知识图谱的统计分析信息"""
        from server.mcp.yuxi_know_tools import get_graph_statistics
        return await get_graph_statistics()

    # =============================================================================
    # === 创建知识库工具 ===
    # =============================================================================
    @mcp_router.post("/knowledge/base/create", operation_id="yuxi-know-create-kb", response_model=dict)
    async def yuxi_know_create_kb(data: dict = Body(...)):
        """创建新的知识库，支持多种类型和配置选项"""
        from server.mcp.yuxi_know_tools import create_knowledge_base, KnowledgeBaseCreateInput

        from server.mcp.yuxi_know_tools import KnowledgeBaseCreateInput

        kb_data = KnowledgeBaseCreateInput(
            name=data.get("name"),
            description=data.get("description"),
            kb_type=data.get("kb_type", "LightRAG"),
            embedding_model=data.get("embedding_model", "bge-m3"),
            llm_info=data.get("llm_info")
        )

        return await create_knowledge_base(kb_data)

    return mcp_router

def setup_mcp_server(fastapi_app: FastAPI = None,
                    api_base_url: str = None,
                    api_key: str = None,
                    mount_path: str = None) -> Optional[Any]:
    """
    设置MCP服务器

    Args:
        fastapi_app: FastAPI应用实例
        api_base_url: API基础URL
        api_key: API密钥
        mount_path: MCP挂载路径

    Returns:
        MCP服务器实例，如果MCP未启用则返回None
    """
    if not MCP_ENABLED:
        logger.info("MCP功能已禁用")
        return None

    try:
        # 尝试导入fastapi_mcp
        try:
            from fastapi_mcp import FastApiMCP
        except ImportError:
            logger.error("fastapi_mcp依赖未安装，请先安装：uv add fastapi-mcp")
            return None

        # 获取FastAPI应用实例
        app = fastapi_app
        if app is None:
            logger.error("需要提供FastAPI应用实例")
            return None

        # 创建MCP工具路由器
        mcp_router = create_mcp_router()

        # 将MCP工具路由器添加到FastAPI应用
        app.include_router(mcp_router)

        # 创建MCP服务器实例
        mcp_server = FastApiMCP(
            app,  # FastAPI应用实例
            name=MCP_SERVER_NAME,
            description=f"{MCP_SERVER_NAME} - {MCP_SERVER_VERSION}"
        )

        # 挂载MCP服务器
        mount_path = mount_path or MCP_MOUNT_PATH
        mcp_server.mount_http(mount_path=mount_path)

        logger.info(f"✅ Yuxi-Know MCP服务器已启动，挂载路径: {mount_path}")
        logger.info(f"🚀 MCP服务器信息:")
        logger.info(f"   名称: {MCP_SERVER_NAME}")
        logger.info(f"   版本: {MCP_SERVER_VERSION}")
        logger.info(f"   API地址: {api_base_url or os.getenv('YUXI_KNOW_API_URL', 'http://localhost:5050/api')}")

        return mcp_server

    except Exception as e:
        logger.error(f"启动MCP服务器失败: {e}")
        logger.exception("MCP服务器启动异常")
        return None